package com.dy.yunying.biz.service.data.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.dy.yunying.api.dto.HourDataDto;
import com.dy.yunying.api.entity.ParentGameDO;
import com.dy.yunying.api.vo.HourDataVo;
import com.dy.yunying.biz.dao.clickhouse3399.impl.HourDataDao;
import com.dy.yunying.biz.service.data.HourDataService;
import com.dy.yunying.biz.service.manage.AdRoleUserService;
import com.dy.yunying.biz.service.manage.GameChannelPackService;
import com.dy.yunying.biz.service.manage.ParentGameService;
import com.dy.yunying.biz.utils.DateUtils;
import com.google.common.collect.Lists;
import com.pig4cloud.pig.api.feign.RemoteAccountService;
import com.pig4cloud.pig.common.core.constant.SecurityConstants;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.security.service.PigUser;
import com.pig4cloud.pig.common.security.util.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * @ClassName HourDataServiceImpl
 * @Description done
 * @Author nieml
 * @Time 2021/6/24 14:55
 * @Version 1.0
 **/

@Service
@Slf4j
public class HourDataServiceImpl implements HourDataService {

	@Autowired
	private HourDataDao hourDataDaoNew;
	@Autowired
	private AdRoleUserService adRoleUserService;

	@Autowired
	private RemoteAccountService remoteAccountService;

	@Autowired
	private ParentGameService parentGameService;

	@Autowired
	private GameChannelPackService gameChannelPackService;

	@Override
	public R selectHourData(HourDataDto req) {
		try {
			// 当前用户
			final PigUser user = SecurityUtils.getUser();
			List<Integer> ownerRoleUserIds = adRoleUserService.getOwnerRoleUserIds();
			// 当前账号及管理的账号
			List<Integer> roleUserIdList = new ArrayList<>();
			req.setRoleUserIdList(roleUserIdList);
			roleUserIdList.add(user.getId());
			roleUserIdList.addAll(ownerRoleUserIds);

			// 授权的广告账户
			List<String> roleAdAccountList = new ArrayList<>();
			req.setRoleAdAccountList(roleAdAccountList);
			final List<String> accountList2 = remoteAccountService.getAccountList2(ownerRoleUserIds, SecurityConstants.FROM_IN);
			if (ObjectUtils.isNotEmpty(accountList2)) {
				roleAdAccountList.addAll(accountList2);
			}

			// 判断是否管理员
			if (SecurityUtils.getRoles().contains(1)) {
				req.setIsSys(1);
			}

			List<HashMap<String, String>> hourDataResult = this.getHourDataResult(req);
			return R.ok(hourDataResult);
		} catch (Exception e) {
			log.error("selectHourData:{}", e);
			return R.failed("分时报表查询失败");
		}
	}

	private void deal(List<HourDataVo> hourDataVos) {
		if (CollectionUtils.isNotEmpty(hourDataVos)) {

			//分包编码名称
			List<String> appChlArr = new ArrayList<>();
			if (ObjectUtils.isNotEmpty(hourDataVos)) {
				hourDataVos.forEach(dataAccount -> {
					String appchl = dataAccount.getAppchl();
					if (org.apache.commons.lang3.StringUtils.isNotBlank(appchl)) {
						appChlArr.add(appchl);
					}
				});
			}
			List<Map<String, String>> appChlArrList = gameChannelPackService.queryAppChlName(appChlArr);
			Map<String, String> mapappChl = new HashMap<>();
			if (ObjectUtils.isNotEmpty(appChlArrList)) {
				appChlArrList.forEach(appChlData -> {
					mapappChl.put(String.valueOf(appChlData.get("code")), appChlData.get("codeName"));
				});
			}

			for (HourDataVo hourDataVo : hourDataVos) {
				try {
					final Long pgid = hourDataVo.getPgid();

					final ParentGameDO parentGameDO = parentGameService.getByPK(pgid);
					String parentGameName = "未知";
					if (parentGameDO != null) {
						parentGameName = parentGameDO.getGname();
					}
					hourDataVo.setParentGameName(parentGameName);

					// 分包编码名称
					String appchl = hourDataVo.getAppchl();
					hourDataVo.setAppchl(mapappChl.get(appchl) == null ? appchl : mapappChl.get(appchl));
				} catch (Exception e) {
					log.error("数据处理异常", e);
				}
			}
		}
	}

	//组装汇总结果及维度结果，转换为原型格式
	public List<HashMap<String, String>> getHourDataResult(HourDataDto req) {
		//查询分时数据结果
		String queryColumn = req.getQueryColumn();
		List<HourDataVo> allList = hourDataDaoNew.getHourDataAll(req);
		deal(allList);
		List<HourDataVo> list = null;
		if (StringUtils.isNotBlank(queryColumn)) {
			list = hourDataDaoNew.getHourDataDim(req);
			deal(list);
		}


		//组装结果
		List<HashMap<String, String>> mapList = Lists.newArrayList();
		// 汇总
		if (req.getCycleType() == 4) {
			// 有类别汇总
			if (StringUtils.isNotBlank(queryColumn)) {
				HashMap<String, String> hColumnMap = new HashMap<>();
				String queryKpiValue = getQueryKpiValue(req, allList.get(0));
				list.forEach(hdata -> {
					String querykpiValueColumn = getQueryKpiValue(req, hdata);
					String queryColumnValue = getQueryColumnValue(req, hdata);
					hColumnMap.put(queryColumnValue, querykpiValueColumn);
					hColumnMap.put("hour", "汇总");
					hColumnMap.put("all", queryKpiValue);
					mapList.add(hColumnMap);
				});
			} else {
				// 无类别汇总
				HashMap<String, String> huizongMap = new HashMap<>();
				String queryKpiValue = getQueryKpiValue(req, allList.get(0));
				huizongMap.put("all", queryKpiValue);
				huizongMap.put("hour", "汇总");
				mapList.add(huizongMap);
			}
		} else {
			List<Integer> hourList = getHourList(req);
			for (int i = 0; i < hourList.size(); i++) {
				HashMap<String, String> lineMap = new HashMap<>();
				Integer hour = hourList.get(i);
				long hourLong = hour.longValue();
				lineMap.put("hour", hour.toString());
				allList.forEach(allLine -> {
					Long dataHour = allLine.getHour();
					if (dataHour != null) {
						if (hourLong == dataHour) {
							String queryKpiValue = getQueryKpiValue(req, allLine);
							lineMap.put("all", queryKpiValue);
						}
					}
				});
				//如果类别为空则直接返回
				if (StringUtils.isNotBlank(queryColumn)) {
					list.forEach(line -> {
						Long dataHour = line.getHour();
						if (hourLong == dataHour) {
							String queryKpiValue = getQueryKpiValue(req, line);
							String queryColumnValue = getQueryColumnValue(req, line);
							lineMap.put(queryColumnValue, queryKpiValue);
						}
					});
				}
				mapList.add(lineMap);
			}
		}

		return mapList;
	}

	//获取查询的维度的列值：如选择pgid，返回:父游戏xx
	private String getQueryKpiValue(HourDataDto req, HourDataVo line) {
		String hourDataKpi = req.getHourDataKpi();
		switch (hourDataKpi) {
			case "reg":
				return line.getNewRegNums().toString();
			case "pay":
				BigDecimal newRegPayAmount = line.getNewRegPayAmount();
				newRegPayAmount = newRegPayAmount == null ? BigDecimal.ZERO : newRegPayAmount.setScale(2, RoundingMode.HALF_UP);
				return newRegPayAmount.toString();
			case "ltv":
				return line.getLtv().toString();

			default:
				//todo
				return line.getNewRegNums().toString();
		}
	}

	//获取查询的维度的列值：如选择pgid，返回:父游戏xx
	private String getQueryColumnValue(HourDataDto req, HourDataVo line) {
		String queryColumn = req.getQueryColumn();
		switch (queryColumn) {
			case "pgid":
				return line.getParentGameName() + "(" + line.getPgid() + ")";
			case "gameid":
				return line.getGName() + "(" + line.getGameid() + ")";
			case "parentchl":
				return line.getParentchlName() + "(" + line.getParentchl() + ")";
			case "appchl":
				return line.getAppchl();
			case "investor":
				return line.getInvestorName() + "(" + line.getInvestor() + ")";
			case "deptId":
				return line.getDeptName() + "(" + line.getDeptId() + ")";
			case "userGroupId":
				return line.getUserGroupName() + "(" + line.getUserGroupId() + ")";
			default:
				//todo
				return "";
		}
	}

	// 获取小时List
	private List<Integer> getHourList(HourDataDto req) {
		String newteday = DateUtils.dateToString(new Date(), DateUtils.YYYYMMDD);// 今天
		Long date = req.getDate();
		String dateStr = Long.toString(date);
		if (dateStr.equals(newteday)) {
			List<Integer> list = new ArrayList<Integer>();
			Integer hour = new Date().getHours();
			for (int i = 0; i <= hour; i++) {
				list.add(hour - i);
			}
			return list;
		}
		List<Integer> hourList = Arrays.asList(23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
		return hourList;
	}

}
